package utils

import (
	"context"
	"log"
	"sync"
	"time"

	"github.com/adshao/go-binance/v2"
)

// TimeSyncManager 时间同步管理器
type TimeSyncManager struct {
	timeOffset int64 // 时间偏移量（毫秒）
	mu         sync.RWMutex
	lastSync   time.Time
}

var (
	timeSyncManager *TimeSyncManager
	syncOnce        sync.Once
)

// GetTimeSyncManager 获取时间同步管理器单例
func GetTimeSyncManager() *TimeSyncManager {
	syncOnce.Do(func() {
		timeSyncManager = &TimeSyncManager{
			timeOffset: 0,
			lastSync:   time.Time{},
		}
	})
	return timeSyncManager
}

// SyncWithBinanceServer 与Binance服务器同步时间
func (tsm *TimeSyncManager) SyncWithBinanceServer(client *binance.Client) error {
	tsm.mu.Lock()
	defer tsm.mu.Unlock()

	// 获取Binance服务器时间
	serverTimeService := client.NewServerTimeService()
	serverTimeRes, err := serverTimeService.Do(context.Background())
	if err != nil {
		log.Printf("获取Binance服务器时间失败: %v", err)
		return err
	}

	// 计算时间偏移量
	localTime := time.Now().UnixMilli()
	serverTime := serverTimeRes
	tsm.timeOffset = serverTime - localTime
	tsm.lastSync = time.Now()

	log.Printf("时间同步完成 - 服务器时间: %d, 本地时间: %d, 偏移量: %d ms", 
		serverTime, localTime, tsm.timeOffset)

	return nil
}

// GetSyncedTimestamp 获取同步后的时间戳
func (tsm *TimeSyncManager) GetSyncedTimestamp() int64 {
	tsm.mu.RLock()
	defer tsm.mu.RUnlock()

	// 如果超过5分钟没有同步，返回当前时间减去安全偏移量
	if time.Since(tsm.lastSync) > 5*time.Minute {
		// 使用15秒的安全偏移量
		return time.Now().UnixMilli() - 15000
	}

	return time.Now().UnixMilli() + tsm.timeOffset
}

// GetTimeOffset 获取当前时间偏移量
func (tsm *TimeSyncManager) GetTimeOffset() int64 {
	tsm.mu.RLock()
	defer tsm.mu.RUnlock()
	return tsm.timeOffset
}

// IsTimeSync 检查时间是否已同步
func (tsm *TimeSyncManager) IsTimeSync() bool {
	tsm.mu.RLock()
	defer tsm.mu.RUnlock()
	return !tsm.lastSync.IsZero() && time.Since(tsm.lastSync) < 10*time.Minute
}

// AutoSync 自动同步时间（建议在程序启动时调用）
func (tsm *TimeSyncManager) AutoSync(client *binance.Client) {
	// 立即同步一次
	if err := tsm.SyncWithBinanceServer(client); err != nil {
		log.Printf("初始时间同步失败: %v", err)
	}

	// 启动定时同步
	go func() {
		ticker := time.NewTicker(5 * time.Minute) // 每5分钟同步一次
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				if err := tsm.SyncWithBinanceServer(client); err != nil {
					log.Printf("定时时间同步失败: %v", err)
				}
			}
		}
	}()
}